package redis

import (
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-redsync/redsync/v4"
	redsyncredis "github.com/go-redsync/redsync/v4/redis"
	"github.com/go-redsync/redsync/v4/redis/goredis/v9"
	"github.com/redis/go-redis/v9"
	"log"
	"time"
)

func NewRedLock() (*redsync.Redsync, error) {
	// 连接三个 Redis 节点
	clients := []redis.UniversalClient{
		redis.NewClient(&redis.Options{Addr: "localhost:6379"}),
		redis.NewClient(&redis.Options{Addr: "localhost:6380"}),
		redis.NewClient(&redis.Options{Addr: "localhost:6381"}),
	}

	// 创建 RedLock 池
	pools := make([]redsyncredis.Pool, 0, len(clients))
	for _, client := range clients {
		pools = append(pools, goredis.NewPool(client))
	}

	// 初始化 Redsync 实例
	rs := redsync.New(pools...)
	return rs, nil
}

func BusinessOperation(ctx context.Context) error {
	// 初始化 RedLock
	rs, err := NewRedLock()
	if err != nil {
		return err
	}

	// 创建锁对象（锁名为唯一标识）
	mutex := rs.NewMutex("order:lock:123",
		redsync.WithExpiry(10*time.Second), // 锁超时时间
		redsync.WithTries(3),               // 重试次数
		redsync.WithRetryDelay(500*time.Millisecond),
	)

	// 尝试加锁
	if err := mutex.LockContext(ctx); err != nil {
		return fmt.Errorf("lock failed: %v", err)
	}

	// 确保解锁（使用 defer 防止忘记释放）
	defer func() {
		if _, err := mutex.UnlockContext(ctx); err != nil {
			log.Printf("unlock failed: %v", err)
		}
	}()

	// 执行关键业务逻辑
	//if err := ProcessOrder(); err != nil {
	//	return err
	//}

	return nil
}

func LockMiddleware(rs *redsync.Redsync) gin.HandlerFunc {
	return func(c *gin.Context) {
		resourceID := c.Param("id")
		lockName := fmt.Sprintf("resource:%s:lock", resourceID)

		mutex := rs.NewMutex(lockName,
			redsync.WithExpiry(15*time.Second),
			redsync.WithTries(3),
		)

		// 加锁
		if err := mutex.LockContext(c.Request.Context()); err != nil {
			c.AbortWithStatusJSON(503, gin.H{"error": "resource busy"})
			return
		}

		// 确保解锁
		defer func() {
			if _, err := mutex.UnlockContext(c.Request.Context()); err != nil {
				log.Printf("unlock failed: %s", lockName)
			}
		}()

		c.Next()
	}
}
